package com.fare.taluo.core.domain.crawl.adapter.sub;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.regex.Pattern;

import net.htmlparser.jericho.Element;
import net.htmlparser.jericho.Source;

import org.apache.commons.lang3.StringUtils;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.cookie.Cookie;
import org.apache.http.impl.client.AbstractHttpClient;
import org.apache.http.params.CoreConnectionPNames;
import org.apache.http.util.EntityUtils;

import com.fare.taluo.conf.ConfigContainer;
import com.fare.taluo.core.domain.config.city.PortEntity;
import com.fare.taluo.core.domain.config.line.FlightInfoEntity;
import com.fare.taluo.core.domain.crawl.CrawlCSAirLineModel;
import com.fare.taluo.core.domain.crawl.adapter.AbstractAdapter;
/**
 * 
 * 南航航线的验证保存适配器
 * 
 * */
public class CSAirLineAdaptor extends AbstractAdapter {
	private HttpClient client = null;
	private String cookeiStr;
	private String referer;
	
	public CSAirLineAdaptor(CrawlCSAirLineModel portModel) {
		super(portModel);
		
	}

	@Override
	public String getUrl() throws Exception {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public Object fetch(String url) throws Exception {
		String s;
		try {
			setReferer("http://www.csair.com/cn/");
			fetchURI(produceWaittingUri());
			setRequestDatas();
			setReferer("http://www.csair.com/cn/tourguide/flight_info/flight_dynamic/");
			s = fetchURI(produceUri());
			return s;
		} finally {
			referer = null;
			cookeiStr = null;
			client = null;
		}
	}
	
	private URI produceUri() throws URISyntaxException {
		return (new URIBuilder()).addParameter("arvArpCdSelect0", portModel.getToCity())
				.addParameter("depArpCdSelect0", portModel.getFromCity())
				.addParameter("queryType", portModel.getQueryType())
				.setScheme("http").setHost("eb.csair.com")
				.setPath("/flightQuery/fltQueryETicketResultN.jsp").build();
		//http://eb.csair.com/flightQuery/fltQueryETicketResultN.jsp
	}
	
	private void setRequestDatas() {
		AbstractHttpClient aclient = (AbstractHttpClient) client;
		List<Cookie> cookies = aclient.getCookieStore().getCookies();
		StringBuilder sbuilder = new StringBuilder();
		Cookie c;
		for (Iterator<Cookie> iterator = cookies.iterator(); iterator.hasNext(); sbuilder
				.append(c.getName()).append("=").append(c.getValue())
				.append(";"))
			c = (Cookie) iterator.next();

		cookeiStr = sbuilder.toString();
	}
	private String fetchURI(URI uri) throws Exception {
		HttpPost request;
		HttpEntity entity;
		byte data[];
		request = null;
		HttpResponse response = null;
		entity = null;
		InputStream is = null;
		data = null;
		String s;
		try {
			if (client == null)
				client = super.getHttpClient();
			client.getParams().setIntParameter(CoreConnectionPNames.CONNECTION_TIMEOUT,1000000);
		        //响应超时
			client.getParams().setParameter(CoreConnectionPNames.SO_TIMEOUT, 1000000);
			request = new HttpPost(uri);
			request.setHeader("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8");
			request.setHeader("Accept-Encoding", "gzip, deflate");
			request.setHeader("Accept-Language", "zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3");
			request.setHeader("Connection", "keep-Alive");
			request.setHeader("Cache-Control", "no-cache");
			request.setHeader("Content-Type",
					"application/x-www-form-urlencoded");
			if (StringUtils.isNotBlank(cookeiStr))
				request.setHeader("Cookie", cookeiStr);
			request.setHeader("Host", "eb.csair.com");
			request.setHeader("User-Agent",
					"Mozilla/5.0 (Windows NT 6.1; WOW64; rv:21.0) Gecko/20100101 Firefox/21.0");
			request.setHeader("Referer", referer);
			response = client.execute(request);
			entity = response.getEntity();
			if (entity != null) {
				is = entity.getContent();
				data = writeByte(is);
			}

			s = new String(data, "UTF-8");
		} finally {
			if (is != null)
				try {
					is.close();
				} catch (Exception e) {
				}
			;
			is = null;
			if (request != null)
				request.releaseConnection();
			if (entity != null)
				EntityUtils.consume(entity);
			entity = null;
			response = null;
			request = null;
		}
		return s;
	}

	
	
	private URI produceWaittingUri() throws URISyntaxException {
		URI uri = new URIBuilder().addParameter("type", "on")
		.addParameter("doaction", "/flightQuery/fltQueryETicketResultN.jsp")
		.addParameter("depArpCdSelect0", portModel.getFromCity())
		.addParameter("arvArpCdSelect0", portModel.getToCity())
		.addParameter("queryType", portModel.getQueryType())
		.setScheme("http")
		.setHost("eb.csair.com").setPath("/tourguide/flight_info/flight_dynamic/")
		.build();
		return uri;//http://eb.csair.com/flightQuery/fltQueryETicketResultN.jsp
	}
	
	public List<Object> paraseToVo(Object fetchObject,Map<String,PortEntity> map) {
 		String tempResult = fetchObject.toString();
		List<Object> list = parseSource(new Source(tempResult),map);
		tempResult = null;
		return list;
	}
	
	private List<Object> parseSource(Source source,Map<String,PortEntity> map) {
		List<Object> dataList = new ArrayList<Object>();
		List<Element> elementList = source.getAllElements("table");
        for (Iterator iterator = elementList.iterator(); iterator.hasNext();) {
			Element element = (Element) iterator.next();
			List<Element> trLists = element.getAllElements("tr");
			for (int i = 1; i < trLists.size(); i++) {			
				String startTime = getTableContent(element, i, 1)
						.getTextExtractor().toString();
				String[] data = startTime.split(" ");
				Calendar cal=Calendar.getInstance();    
				int m = cal.get(Calendar.DATE);
				if(data[0].substring(3, 4).equals("0")){
					if(!data[0].substring(4, 5).equals(""+m)){
						continue;
					}
				} 
				if((""+m).length()>1 && !data[0].substring(3, 5).equals(""+m)  ){
					continue;
				}
				
				if(getTableContent(element, i, 2).getTextExtractor().toString().equals("航班取消")){
					//System.out.println("----------");
					continue;
				}
				
				String flightDate = data[0];
				String flightId = getTableContent(element, i, 0)
						.getTextExtractor().toString();		
				String endTime = getTableContent(element, i, 4)
						.getTextExtractor().toString();
				String fromCityName = getTableContent(element, i, 3)
						.getTextExtractor().toString();
				String toCityName = getTableContent(element, i, 6)
						.getTextExtractor().toString();

					FlightInfoEntity entity = new FlightInfoEntity();
					entity.setFlightNo(flightId);
					entity.setFlightStartTime(data[1]);
					entity.setFlightEndTime(endTime.split(" ")[1]);
					entity.setFromCityName(fromCityName);
					if(null != map.get(fromCityName)){
						entity.setFromCity(map.get(fromCityName).getCode());
					}
					if(null != map.get(toCityName)){
						entity.setToCity(map.get(toCityName).getCode());
					}
					entity.setToCityName(toCityName);
					entity.setFlightDate(flightDate);
					entity.setCompanyCode("CZ");
					entity.setCompanyName("南方航空");
					entity.setEntryTime(new Date());
					dataList.add(entity);
			}	
		}		
		return dataList;
	}
	
	public Element getTableContent(Element element, int rows, int cols) {
		Element resultElement = null;
		List<Element> trList = element.getAllElements("tr");

		if (rows < trList.size()) {
			Element trElement = (Element) trList.get(rows);
			List<Element> tdList = trElement.getAllElements("td");
			if (cols < tdList.size())
				resultElement = (Element) tdList.get(cols);
		}
		return resultElement;
	}
	
	protected byte[] writeByte(InputStream is) throws IOException {
		int count = 0;
		if (is == null)
			return new byte[0];
		ByteArrayOutputStream os = null;
		byte[] data = null;
		try {
			os = new ByteArrayOutputStream();
			data = new byte[1024];
			while ((count = is.read(data)) > 0)
				os.write(data, 0, count);

			return os.toByteArray();
		} finally {
			os = null;
			data = null;
		}
	}
	@Override
	public boolean validateFetch(Object fetchObject) throws Exception {
		// TODO Auto-generated method stub
		return false;
	}
    
	
	
	public HttpClient getClient() {
		return client;
	}

	public void setClient(HttpClient client) {
		this.client = client;
	}

	public String getCookeiStr() {
		return cookeiStr;
	}

	public void setCookeiStr(String cookeiStr) {
		this.cookeiStr = cookeiStr;
	}

	public String getReferer() {
		return referer;
	}

	public void setReferer(String referer) {
		this.referer = referer;
	}

	public static void main(String[] args) throws Exception {
		CrawlCSAirLineModel portModel = new CrawlCSAirLineModel();
		portModel.setFromCity("AQG");
		portModel.setToCity("CAN");
		portModel.setQueryType("depArvCode");
		ConfigContainer.getInstance().register("com.fare.taluo.core.domain.crawl.CrawlPropertiesLoader");
		CSAirLineAdaptor adap = new CSAirLineAdaptor(portModel);
		Object obj = adap.fetch(null);
		if(!obj.toString().contains("您查询的航班不存在")){
			System.out.println(obj.toString());
			//删除<script>..</script>
			String parseStr = Pattern.compile("<script.*?>.*?</script>", Pattern.CASE_INSENSITIVE).matcher(obj.toString()).replaceAll("<td>");  
			List<Object> results = adap.paraseToVo(parseStr);
			System.out.println(results.size());
		}
		
	}

	@Override
	public List<Object> paraseToVo(Object fetchObject) throws Exception {
		// TODO Auto-generated method stub
		return null;
	}
}
